package com;

import com.jfinal.kit.Kv;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.activerecord.generator.DataDictionaryGenerator;
import com.jfinal.plugin.activerecord.generator.MetaBuilder;
import com.jfinal.plugin.activerecord.generator.TableMeta;

import javax.sql.DataSource;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class CodeGenerator {
    static CodeGenerator generator = new CodeGenerator();
    protected final JfEnjoy jfEngine    = new JfEnjoy();
    public List<String> modelList = new ArrayList<String>();

    protected Kv tablemetaMap       = null;
    protected String srcFolder      = "src/main/java";
    protected String viewFolder     = "src/main/webapp";
    protected String basePath       = "com.zhangyue.web";
    protected String templetePackage = "com.templete.java";
    protected String htmlTempletePackage = "com.templete.html";
    protected String commonHtmlTempletePackage = "com.templete.common";

    public static void main( String[] args ){
        generator.loadConfig();
        generator.generatorModel();
        generator.generatorJava();
        generator.generatorHTML();
        generator.generatorCommon();
        generator.generatorConfig();
    }

    private void generatorConfig() {
        String rootJavaPath = new StringBuffer(System.getProperty("user.dir")).append("/").append(srcFolder).toString();
        String templetePath = new StringBuffer(rootJavaPath).append("/com/templete").toString();
        String outJavaPath = new StringBuffer(rootJavaPath).append("/com/zhangyue/core/config/BaseConfig.java").toString();
        Kv kv = Kv.by("package",basePath);
        jfEngine.generatorCode(templetePath,"BaseConfig.html",kv,outJavaPath);
    }

    private void loadConfig() {
        PropKit.use("db.properties");
        srcFolder = PropKit.get("srcFolder");
        viewFolder = PropKit.get("viewFolder");
        basePath = PropKit.get("basePath");
        templetePackage = PropKit.get("templetePackage");
        htmlTempletePackage = PropKit.get("htmlTempletePackage");
        commonHtmlTempletePackage = PropKit.get("commonHtmlTempletePackage");

    }

    public void generatorHTML(){
        for(String className : modelList){
           TableMeta tableMeta = getTableMeta(className);
           htmlList(className,tableMeta);
        }
        System.out.println("---------- html generator over ----------------");
    }

    public void htmlList(String className, TableMeta tablemeta){
        String htmlTempTempletePath = FileNameUtil.toPathByPackage(htmlTempletePackage);
        String rootHtmlPath = new StringBuffer(System.getProperty("user.dir")).append("/").append(viewFolder).append("/").append(FileNameUtil.toSmallClassName(className)).toString();
        String rootJavaPath = new StringBuffer(System.getProperty("user.dir")).append("/").append(srcFolder).toString();
        String templetePath = new StringBuffer(rootJavaPath).append("/").append(htmlTempTempletePath).toString();

        jfEngine.render(templetePath,
                Kv.by("tablemeta", tablemeta).set("rootHtmlPath", rootHtmlPath ).set("smallClassName",FileNameUtil.toSmallClassName(className))
        );
    }

    public void generatorJava() {
        String tempTempletePath = FileNameUtil.toPathByPackage(templetePackage);
        String rootJavaPath = new StringBuffer(System.getProperty("user.dir")).append("/").append(srcFolder).toString();
        String templetePath = new StringBuffer(rootJavaPath).append("/").append(tempTempletePath).toString();
        Kv kv = Kv.by("package",basePath);
        kv.set("rootJavaPath",rootJavaPath);
        for(String className : modelList){
            kv.set("className",className);
            kv.set("smallClassName",FileNameUtil.toSmallClassName(className));
            kv.set("suffix",".java");
            jfEngine.render(templetePath,kv);
        }
        System.out.println("---------- java generator over ----------------");
    }

    private void generatorCommon() {
        String htmlTempTempletePath = FileNameUtil.toPathByPackage(commonHtmlTempletePackage);
        String rootHtmlPath = new StringBuffer(System.getProperty("user.dir")).append("/").append(viewFolder).append("/").append("common").toString();
        String rootJavaPath = new StringBuffer(System.getProperty("user.dir")).append("/").append(srcFolder).toString();
        String templetePath = new StringBuffer(rootJavaPath).append("/").append(htmlTempTempletePath).toString();

        jfEngine.render(templetePath,
                tablemetaMap.set("rootHtmlPath", rootHtmlPath )
        );
        System.out.println("---------- Common generator over ----------------");
    }

    protected class DataGenerator extends DataDictionaryGenerator {
        public DataGenerator(DataSource dataSource, String dataDictionaryOutputDir) {
            super(dataSource, dataDictionaryOutputDir);
        }
        public void rebuildColumnMetas(List<TableMeta> tableMetas) {
            super.rebuildColumnMetas(tableMetas);
        }
    };

    public TableMeta getTableMeta(String tableName){
        if( tablemetaMap == null ){

            DataSource dataSource = App.getDataSource();

            MetaBuilder metaBuilder = new MetaBuilder(dataSource);
            metaBuilder.setDialect(new MysqlDialect());
            //metaBuilder.addExcludedTable(_JFinalDemoGenerator.excludedTable);
            List<TableMeta> tableMetas = metaBuilder.build();
            new DataGenerator(dataSource, null).rebuildColumnMetas(tableMetas);

            if (tableMetas.size() == 0) {
                System.out.println("TableMeta 数量为 0，不生成任何文件");
                return null;
            }
            Kv kv = Kv.create();
            for (TableMeta tableMeta : tableMetas) {
                kv.set(FileNameUtil.toClassByTable(tableMeta.name), tableMeta);
            }
            kv.set("tableList",tableMetas);
            tablemetaMap = kv;
        }
        return (TableMeta) tablemetaMap.get(tableName);
    }

    public String toPackageByPath(String path){
        return path.replaceAll("/",".");
    }

    /**
     * clazz  自动生成Model的App代码
     *
     * */
    public CodeGenerator generatorModel(){
        String path = App.GeneratorModel();
        System.out.println("---------- Model generator over ----------------");
        getModeName(path);
        return this;
    }

    private void getModeName(String path) {
        File file = new File(path);
        for(File f: file.listFiles()){
            if(f.isFile() && !f.getName().contains("_MappingKit")){
                modelList.add(FileNameUtil.subSuffix(f.getName()));
            }
        }
    }

}
